package com.erp.erp_ui.warehouse.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.erp.enums.*;
import com.erp.erp_entitys.warehouse.entity.*;
import com.erp.erp_entitys.warehouse.req.InitStatisticsInfoReq;
import com.erp.erp_entitys.warehouse.req.InitStockListReq;
import com.erp.erp_entitys.warehouse.req.ProductInfoReq;
import com.erp.erp_entitys.warehouse.rsp.InitStatisticsInfoRsp;
import com.erp.erp_entitys.warehouse.rsp.InitStockListRsp;
import com.erp.erp_entitys.warehouse.rsp.ProductInfoRsp;
import com.erp.erp_servers.warehouse.*;
import com.erp.erp_ui.money.req.OperationReq;
import com.erp.erp_ui.warehouse.enums.DataIsValidEnum;
import com.erp.erp_ui.warehouse.enums.DataSourceTitleEnum;
import com.erp.erp_ui.warehouse.req.*;
import com.erp.erp_ui.warehouse.vo.*;
import com.erp.utils.DateUtils;
import com.erp.utils.R;
import com.erp.utils.ResultStatusEnum;
import com.erp.utils.StringUtil;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName : InitStockService
 * @Description : 初始化库存业务逻辑层
 * @Author : lst
 * @Date: 2020-07-22 13:46
 */
@Service
public class InitStockService {

    /**
     * 日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(InitStockService.class);

    /**
     * 初始化库存接口
     */
    private final IInitStockService initStockService;

    /**
     * 初始化库存明细接口
     */
    private final IInitStockDetailService initStockDetailService;

    /**
     * 库存接口
     */
    private final IStockService stockService;

    /**
     * 库存明细接口
     */
    private final IStockDetailService stockDetailService;

    /**
     * 附件接口
     */
    private final IAnnexService annexService;

    /**
     * 临时附件接口
     */
    private final ITempAnnexService tempAnnexService;

    @Autowired
    public InitStockService(IInitStockService initStockService,
                            IInitStockDetailService initStockDetailService,
                            IStockService stockService,
                            IStockDetailService stockDetailService,
                            IAnnexService annexService,
                            ITempAnnexService tempAnnexService) {
        this.initStockService = initStockService;
        this.initStockDetailService = initStockDetailService;
        this.stockService = stockService;
        this.stockDetailService = stockDetailService;
        this.annexService = annexService;
        this.tempAnnexService = tempAnnexService;
    }


    /**
     * 仓库管理-初始化-首页-分页查询
     * @param req 查询条件
     * @return 分页结果
     */
    public PageInfo<InitStockPageListVo> getListByPage(InitStockPageListReq req){
        //初始化查询条件
        InitStockListReq pageReq = new InitStockListReq();
        //赋值
        BeanUtils.copyProperties(req, pageReq);
        //调用接口获取查询结果
        List<InitStockListRsp> otherOutStocks = initStockService.getListByQuery(pageReq);
        //获取分页信息
        PageInfo pageInfo = new PageInfo(otherOutStocks);
        //初始化回参集合
        List<InitStockPageListVo> pageVos = new ArrayList<>();
        if(CollectionUtils.isEmpty(otherOutStocks)){
            pageInfo.setList(pageVos);
            return pageInfo;
        }
        for(InitStockListRsp other : otherOutStocks){
            InitStockPageListVo pageVo = new InitStockPageListVo();
            BeanUtils.copyProperties(other, pageVo);
            //日期转换
            pageVo.setCreateDate(DateUtils.format(other.getCreateDate(), DateUtils.DATE_PATTERN));
            //状态转换
            pageVo.setStatusStr(OperationStatusEnum.getDescById(other.getStatus()));

            pageVos.add(pageVo);
        }
        pageInfo.setList(pageVos);
        return pageInfo;
    }


    /**
     * 仓库管理-初始化-获取产品信息
     * @param req 查询条件
     * @return 产品集合
     */
    public PageInfo<InitProductInfoVo> getProductInfoByPage(InitProductInfoReq req){
        //初始化查询参数实体
        ProductInfoReq productInfoReq = new ProductInfoReq();
        //字段赋值
        BeanUtils.copyProperties(req, productInfoReq);
        //调用接口查询结果
        List<ProductInfoRsp> productInfoList = stockService.getProductInfoByQuery(productInfoReq);
        //初始化回参对象集合
        List<InitProductInfoVo> infoVos = new ArrayList<>();
        //获取分页信息
        PageInfo pageInfo = new PageInfo(productInfoList);
        if(CollectionUtils.isEmpty(productInfoList)){
            pageInfo.setList(infoVos);
            return pageInfo;
        }
        for(ProductInfoRsp infoRsp : productInfoList){
            //初始化回参对象
            InitProductInfoVo vo = new InitProductInfoVo();
            //赋值
            BeanUtils.copyProperties(infoRsp, vo);
            //单价类型转换
            BigDecimal unitPrice = new BigDecimal("0");
            if(StringUtils.isNotBlank(infoRsp.getUnitPrice())){
                unitPrice = new BigDecimal(infoRsp.getUnitPrice());
            }
            vo.setUnitPrice(unitPrice);

            //人民币采购价（采购成本）
            BigDecimal purchasePriceRmb = new BigDecimal("0");
            if(StringUtils.isNotBlank(infoRsp.getPurchasePriceRmb())){
                purchasePriceRmb = new BigDecimal(infoRsp.getPurchasePriceRmb());
            }
            vo.setPurchasePriceRmb(purchasePriceRmb);

            //40HQ
            BigDecimal fortyHq = new BigDecimal("0");
            if(StringUtils.isNotBlank(infoRsp.getFortyHq())){
                fortyHq = new BigDecimal(infoRsp.getFortyHq());
            }
            vo.setFortyHq(fortyHq);

            infoVos.add(vo);
        }
        pageInfo.setList(infoVos);
        return pageInfo;
    }

    /**
     * 仓库管理-初始化-获取产品信息
     * @param req 查询条件
     * @return 产品集合
     */
    public List<InitProductInfoVo> getProductInfo(InitProductInfoReq req){
        //初始化查询参数实体
        ProductInfoReq productInfoReq = new ProductInfoReq();
        //字段赋值
        BeanUtils.copyProperties(req, productInfoReq);
        //调用接口查询结果
        List<ProductInfoRsp> productInfoList = stockService.getProductInfoByConcat(productInfoReq);
        //初始化回参对象集合
        List<InitProductInfoVo> infoVos = new ArrayList<>();
        if(CollectionUtils.isEmpty(productInfoList)){
            return infoVos;
        }
        for(ProductInfoRsp infoRsp : productInfoList){
            //初始化回参对象
            InitProductInfoVo vo = new InitProductInfoVo();
            //赋值
            BeanUtils.copyProperties(infoRsp, vo);

            //单价类型转换
            BigDecimal unitPrice = new BigDecimal("0");
            if(StringUtils.isNotBlank(infoRsp.getUnitPrice())){
                unitPrice = new BigDecimal(infoRsp.getUnitPrice());
            }
            vo.setUnitPrice(unitPrice);

            //人民币采购价（采购成本）
            BigDecimal purchasePriceRmb = new BigDecimal("0");
            if(StringUtils.isNotBlank(infoRsp.getPurchasePriceRmb())){
                purchasePriceRmb = new BigDecimal(infoRsp.getPurchasePriceRmb());
            }
            vo.setPurchasePriceRmb(purchasePriceRmb);

            //40HQ
            BigDecimal fortyHq = new BigDecimal("0");
            if(StringUtils.isNotBlank(infoRsp.getFortyHq())){
                fortyHq = new BigDecimal(infoRsp.getFortyHq());
            }
            vo.setFortyHq(fortyHq);

            //外包装长
            BigDecimal outerPackingLong = new BigDecimal("0");
            if(StringUtils.isNotBlank(infoRsp.getOuterPackingLong())){
                outerPackingLong = new BigDecimal(infoRsp.getOuterPackingLong());
            }
            vo.setOuterPackingLong(outerPackingLong);

            //外包装宽
            BigDecimal outerPackingWide = new BigDecimal("0");
            if(StringUtils.isNotBlank(infoRsp.getOuterPackingWide())){
                outerPackingWide = new BigDecimal(infoRsp.getOuterPackingWide());
            }
            vo.setOuterPackingWide(outerPackingWide);

            //外包装高
            BigDecimal outerPackingHeight = new BigDecimal("0");
            if(StringUtils.isNotBlank(infoRsp.getOuterPackingHeight())){
                outerPackingHeight = new BigDecimal(infoRsp.getOuterPackingHeight());
            }
            vo.setOuterPackingHeight(outerPackingHeight);

            infoVos.add(vo);
        }
        return infoVos;
    }

    /**
     * 仓库管理-初始化-新增、修改
     * @param req 新增、修改参数实体
     * @param creator 创建人
     * @param createNo 创建人编码
     * @return 新增、修改结果
     */
    @Transactional(rollbackFor = Exception.class)
    public R add(AddInitStockReq req, String creator, String createNo){
        boolean billNoCheckFlag = (null != req.getId() && req.getBillNo().equals(req.getNewBillNo()));
        if(!billNoCheckFlag){
            //单号做唯一校验
            boolean billNoFlag = checkRepeatBillNo(req.getBillNo());
            if(!billNoFlag){
                return R.buildError(ResultStatusEnum.BILL_NO_REPEAT);
            }
        }
        //第一步：主表新增、修改
        Integer id = addOrUpdate(req, creator, createNo);
        if(null == id){
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }

        //第二部：初始化明细新增以及更新初始化明细数量
        insertDetail(req, id, creator, createNo);

        //第三步：添加附件信息
        boolean flag = addAnnex(req.getAnnexList(), id, creator, createNo);
        if(!flag){
            LOGGER.info("仓库管理-其它出库-批量新增附件异常");
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        //第四步：删除临时附件信息
        deleteTempAnnex(req.getAnnexList());

        return R.build(ResultStatusEnum.SUCCESS);
    }

    /**
     * 批量处理临时附件信息，将临时附件设置为失效
     * @param annexReqs
     */
    private void deleteTempAnnex(List<AnnexReq> annexReqs){
        //没有附件
        if(CollectionUtils.isEmpty(annexReqs)){
            return;
        }
        //存在附件
        for(AnnexReq annex : annexReqs){
            if(null != annex.getNews()){
                //旧附件,不用修改
                continue;
            }
            TempAnnexEntity tempAnnex = new TempAnnexEntity();
            //设置临时附件id
            tempAnnex.setId(annex.getId());
            //设置修改时间
            tempAnnex.setUpdateTime(new Date());
            //将附件设置为失效
            tempAnnex.setValid(0);
            tempAnnexService.update(tempAnnex);
        }

    }

    /**
     * 附件新增
     * @param annexReqs 附件信息
     * @param outStockId 入库id
     * @param operator 操作人
     * @param operatorNo 操作人编码
     * @return 是否新增成功(true:成功 false:失败 )
     */
    private boolean addAnnex(List<AnnexReq> annexReqs, Integer outStockId, String operator, String operatorNo) {
        try {
            //没有附件,不新增
            if(CollectionUtils.isEmpty(annexReqs)){
                return true;
            }
            //存在附件,新增附件信息
            List<AnnexEntity> list = new ArrayList<>();
            //获取旧的附件id集合
            List<Integer> oldIds = new ArrayList<>();
            for(AnnexReq annexReq : annexReqs){
                if(null != annexReq.getNews()){
                    //属于旧附件 只取id,不新增
                    oldIds.add(annexReq.getId());
                    continue;
                }
                AnnexEntity annex = new AnnexEntity();
                BeanUtils.copyProperties(annexReq, annex);
                //设置关联模块id
                annex.setModuleId(ModuleTypeEnum.WAREHOUSE_INIT_STOCK.getId());
                //设置关联模块父id
                annex.setParentId(outStockId);
                //设置上传时间
                annex.setUploadTime(DateUtils.convertStringToDate(annexReq.getUploadTime(), DateUtils.DATE_TIME_PATTERN));
                //设置修改时间
                annex.setUpdateTime(new Date());
                //设置操作人
                annex.setOperator(operator);
                //设置操作人编码
                annex.setOperatorNo(operatorNo);
                //设置数据有效
                annex.setValid(1);

                list.add(annex);
            }
            if(oldIds.size() > 0){
                //通过调拨id获取修改附件信息
                AnnexEntity annex = new AnnexEntity();
                annex.setModuleId(ModuleTypeEnum.WAREHOUSE_INIT_STOCK.getId());
                annex.setParentId(outStockId);
                //获取上次附件信息
                List<AnnexEntity> annexList = annexService.queryAll(annex);
                if(!CollectionUtils.isEmpty(annexList)){
                    //获取上次附件id集合
                    List<Integer> oldAnnexIds = annexList.stream().map(p -> p.getId()).collect(Collectors.toList());
                    //得到被删除的附件id
                    Collection collection = new ArrayList(oldAnnexIds);
                    collection.removeAll(oldIds);
                    if(collection.size() > 0){
                        Iterator<Integer> it = collection.iterator();
                        while (it.hasNext()){
                            int id = it.next();
                            AnnexEntity annexEntity = new AnnexEntity();
                            annexEntity.setId(id);
                            //将被删除的附件设为失效
                            annexEntity.setValid(DataIsValidEnum.INVALID.getId());

                            annexService.update(annexEntity);
                        }
                    }
                }
            }
            if(!CollectionUtils.isEmpty(list)){
                //附件批量新增
                int res = annexService.batchInsert(list);
                if(res == list.size()){
                    return true;
                }
            }
            return true;
        }catch (Exception e){
            throw new RuntimeException();
        }
    }

    /**
     * 明细新增
     * @param req 入参
     * @param id 出库id
     * @param creator 创建人
     * @param createNo 创建人编码
     */
    public void insertDetail(AddInitStockReq req, Integer id, String creator, String createNo){
        if(!CollectionUtils.isEmpty(req.getDetails())){
            //获取修改明细id集合
            List<Integer> newIds = new ArrayList<>();
            //新增明细集合
            List<InitStockDetailEntity> addDetails = new ArrayList<>();
            for(AddInitStockProductReq detailReq : req.getDetails()){
                //初始化明细对象
                InitStockDetailEntity detail = new InitStockDetailEntity();
                //赋值
                BeanUtils.copyProperties(detailReq, detail);
                //设置id
                detail.setInitStockId(id);
                //分摊费用单价
                BigDecimal shareCostPrice = new BigDecimal("0");
                if(StringUtil.isNotEmpty(detailReq.getShareCostPrice())){
                    shareCostPrice = detailReq.getShareCostPrice();
                }
                //成本单价（入库成本）
                BigDecimal costUnitPrice = detailReq.getProductUnitPrice();
                //获取入库数量
                BigDecimal num = detailReq.getProductNum();
                //设置成本小计 = (分摊费用单价 + 成本单价)*入库数量
                BigDecimal cost = shareCostPrice.add(costUnitPrice);
                detail.setCostAmount(cost.multiply(num));
                //设置金额小计 = 单价*数量
                detail.setMoneySubtotal(detailReq.getInstoreUnitPrice().multiply(num));
                //获取托盘入数
                BigDecimal trayNumber = detailReq.getTrayNumber();
                if(StringUtil.isNotEmpty(trayNumber)){
                    //设置总托盘 = 入库数量除以托盘入数
                    detail.setTotalTray(num.divide(trayNumber,2, BigDecimal.ROUND_HALF_UP));
                }
                //设置数据有效性(0:无效 1:有效)
                detail.setValid(DataIsValidEnum.VALID.getId());
                //创建时间
                detail.setCreateDate(new Date());
                //合同类型默认为待定
                detail.setContractType(ContractTypeEnum.TO_BE_DETERMINED.getId());
                //库存明细新增
                int stockDetailId = addStockDetail(detailReq, req.getBillNo(), creator, createNo);

                if(null == detailReq.getId()){
                    //新增

                    //设置明细库存id
                    detail.setStockDetailId(stockDetailId);

                    addDetails.add(detail);
                }else {
                    //修改

                    //获取明细id
                    newIds.add(detailReq.getId());
                    detail.setModifyTime(new Date());
                    initStockDetailService.update(detail);
                }

            }

            //处理被删除的入库明细
            handleBeenDeletedTransferDetail(req, id, newIds);

            if(!CollectionUtils.isEmpty(addDetails)){
                //调用接口保存入库明细
                initStockDetailService.addList(addDetails);
            }
        }
    }

    /**
     * 处理被删除的明细
     * @param req 明细
     * @param id id
     * @param newIds 修改后未被删除的入库明细id集合
     */
    private void handleBeenDeletedTransferDetail(AddInitStockReq req, int id, List<Integer> newIds){
        if(null != req.getId()){
            //修改-找出被删除的入库明细

            InitStockDetailEntity initStockDetailReq = new InitStockDetailEntity();
            //设置入库id
            initStockDetailReq.setInitStockId(id);
            //查询有效数据
            initStockDetailReq.setValid(DataIsValidEnum.VALID.getId());
            //调用接口查询结果
            List<InitStockDetailEntity> details = initStockDetailService.queryAll(initStockDetailReq);
            if(!CollectionUtils.isEmpty(details)){
                //获取出库明细id和库存明细id
                Map<String, Map<Integer, Integer>> stockIdAndStockDetailIdMap = getStockIdAndStockDetailIdMap(details);
                //获取id集合
                List<Integer> oldIds = details.stream().map(p -> p.getId()).collect(Collectors.toList());
                //找出被删除的id
                Collection collection = new ArrayList(oldIds);
                collection.removeAll(newIds);
                if(collection.size() > 0){
                    //遍历删除被删除的明细
                    Iterator<Integer> ids = collection.iterator();
                    while (ids.hasNext()){
                        int deletedId = ids.next();
                        Integer stockId = stockIdAndStockDetailIdMap.get("stockIdMap").get(deletedId);
                        if(null != req.getStatus() && req.getStatus().equals(OperationStatusEnum.APPROVED_BOX.getId())){
                            //如果删除的是已批数据,则对应库存数据设为无效，库存明细数据设为无效
                            //初始化库存对象
                            StockEntity stockReq = new StockEntity();
                            //设置修改主键
                            stockReq.setId(stockId);
                            stockReq.setValid(DataIsValidEnum.INVALID.getId());
                            //库存数据设为无效
                            stockService.update(stockReq);

                            StockDetailEntity stockDetail = new StockDetailEntity();
                            //通过出库明细id获取库存库存明细id
                            Integer stockDetailId = stockIdAndStockDetailIdMap.get("stockDetailIdMap").get(deletedId);
                            stockDetail.setId(stockDetailId);
                            //将库存明细设为无效
                            stockDetail.setValid(DataIsValidEnum.INVALID.getId());
                            stockDetailService.update(stockDetail);
                        }

                        InitStockDetailEntity detail = new InitStockDetailEntity();
                        detail.setId(deletedId);
                        detail.setValid(DataIsValidEnum.INVALID.getId());
                        //将删除的初始化明细设为无效
                        initStockDetailService.update(detail);
                    }
                }
            }
        }
    }

    /**
     * 获取库存id和库存明细id
     * @param details 明细对象
     * @return key为调拨明细id value为库存id和库存明细id
     */
    private Map<String, Map<Integer, Integer>> getStockIdAndStockDetailIdMap(List<InitStockDetailEntity> details){
        //获取集合大小
        int size = details.size();
        //库存明细id
        Map<Integer, Integer> stockDetailIdMap = new HashMap<>(size);
        //库存id
        Map<Integer, Integer> stockIdMap = new HashMap<>(size);
        for(InitStockDetailEntity detail : details){
            stockDetailIdMap.put(detail.getId(), detail.getStockDetailId());
            stockIdMap.put(detail.getId(), detail.getStockId());
        }
        Map<String, Map<Integer, Integer>> map = new HashMap<>(3);
        map.put("stockDetailIdMap", stockDetailIdMap);
        map.put("stockIdMap", stockIdMap);
        return map;
    }

    /**
     * 新增库存明细
     * @param detailReq 入库明细
     * @param billNo 单号
     * @param creator 创建人
     * @param createNo 创建人编码
     */
    private int addStockDetail(AddInitStockProductReq detailReq, String billNo, String creator, String createNo){
        //初始化库存明细对象
        StockDetailEntity stockDetail = new StockDetailEntity();
        //赋值
        BeanUtils.copyProperties(detailReq, stockDetail);
        //设置标题
        stockDetail.setTitle(DataSourceTitleEnum.INIT.getDesc());
        //设置单据编号
        stockDetail.setInvoiceNumber(billNo);
        //设置单价
        stockDetail.setUnitPrice(detailReq.getInstoreUnitPrice());
        //设置数量
        stockDetail.setQuantity(detailReq.getProductNum());
        //设置模块id
        stockDetail.setModuleId(ModuleTypeEnum.WAREHOUSE_INIT_STOCK.getId());
        //设置创建人
        stockDetail.setInStorePerson(creator);
        //设置创建人编码
        stockDetail.setInStoreCode(createNo);
        //设置操作人
        stockDetail.setOperator(creator);
        //设置操作人编码
        stockDetail.setOperationCode(createNo);
        if(null == detailReq.getId()){
            //新增

            //设置创建时间
            stockDetail.setCreateDate(new Date());
            //设置有效性
            stockDetail.setValid(DataIsValidEnum.INVALID.getId());
            stockDetailService.insert(stockDetail);

        }else {
            //修改

            stockDetail.setId(detailReq.getStockDetailId());
            stockDetailService.update(stockDetail);
        }

        return stockDetail.getId();
    }

    /**
     * 新增、修改
     * @param req 参数实体
     * @param creator 创建人
     * @param createNo 创建人编码
     * @return 新增、修改结果
     */
    private Integer addOrUpdate(AddInitStockReq req, String creator, String createNo){
        //初始化对象
        InitStockEntity data = new InitStockEntity();
        //赋值
        BeanUtils.copyProperties(req, data);
        //设置创建人
        data.setOperator(creator);
        //设置创建人编码
        data.setOperationNo(createNo);
        //修改时间
        data.setModifyTime(new Date());
        //设置状态,默认为草稿箱
        data.setStatus(OperationStatusEnum.DRAFT_BOX.getId());

        if(null == req.getId()){
            //新增
            //创建日期
            data.setCreateDate(new Date());
            //设置有效性
            data.setValid(DataIsValidEnum.VALID.getId());
            //调用接口新增
            initStockService.insert(data);
        }else {
            //修改
            initStockService.update(data);
        }
        return data.getId();
    }

    /**
     * 校验库存是否存在同一批数据key:0 不存在 key:1 存在
     * @param list 入库明细集合
     * @return boolean
     */
    private Map<Integer, String> checkInStockData(List<AddInitStockProductReq> list){
        String msg = "";
        for(int i = 0; i < list.size(); i++){
            //获取库存信息
            StockEntity stockReq = new StockEntity();
            stockReq.setLotNo(list.get(i).getLotNo());
            stockReq.setProductCode(list.get(i).getProductCode());
            stockReq.setSpecificationCode(list.get(i).getSpecificationCode());
            stockReq.setWarehouseCode(list.get(i).getWarehouseId());
            //根据库存id获取库存信息
            List<StockEntity> stockInfo = stockService.getTheSameStockInfo(stockReq);
            //同一批次，产品编码  规格编码，仓库id  合同号 如果都相同 则为同一组
            if(!CollectionUtils.isEmpty(stockInfo)){
                if(StringUtils.isBlank(msg)){
                    msg = "第" + (i+1) + "行";
                }else {
                    msg = msg + "," + (i+1) + "行";
                }
            }
        }
        Map<Integer, String> map = new HashMap<>();
        if(StringUtils.isBlank(msg)){
            map.put(0, msg);
        }else {
            map.put(1, msg);
        }
        return map;
    }

    /**
     * 校验单号是否存在
     * @param billNo 单号
     * @return true:不重复 false:重复
     */
    private boolean checkRepeatBillNo(String billNo){
        InitStockEntity req = new InitStockEntity();
        req.setBillNo(billNo);
        List<InitStockEntity> list = initStockService.queryAll(req);
        if(CollectionUtils.isEmpty(list)){
            return true;
        }
        return false;
    }

    /**
     * 获取详情、修改
     * @param id 初始化id
     * @return
     */
    public InitStockUpdateOrDetailVo getDetailInfo(Integer id){
        //初始化回参实体
        InitStockUpdateOrDetailVo vo = new InitStockUpdateOrDetailVo();
        if(null == id){
            return vo;
        }

        //第一步：获取主表信息
        InitStockEntity initStock = initStockService.queryById(id);
        if(null == initStock || null == initStock.getId()){
            return vo;
        }
        //赋值
        BeanUtils.copyProperties(initStock, vo);
        //设置创建时间
        vo.setCreateDate(DateUtils.format(initStock.getCreateDate(), DateUtils.DATE_PATTERN));

        //第二步：获取对应产品信息
        InitStockDetailEntity detailReq = new InitStockDetailEntity();
        //设置入库id
        detailReq.setInitStockId(id);
        //设置数据为有效
        detailReq.setValid(DataIsValidEnum.VALID.getId());
        List<InitStockDetailEntity> details = initStockDetailService.queryAll(detailReq);

        if(!CollectionUtils.isEmpty(details)){
            List<InitStockProductInfoVo> productVos = details.stream().map(p -> {
                InitStockProductInfoVo productVo = new InitStockProductInfoVo();
                //赋值
                BeanUtils.copyProperties(p, productVo);

                return productVo;
            }).collect(Collectors.toList());

            vo.setDetailList(productVos);
        }

        //第三步：获取附件信息
        AnnexEntity annex = new AnnexEntity();
        annex.setModuleId(ModuleTypeEnum.WAREHOUSE_INIT_STOCK.getId());
        annex.setParentId(id);
        List<AnnexEntity> annexList = annexService.queryAll(annex);
        if(!CollectionUtils.isEmpty(annexList)){
            List<AnnexVo> annexVos = annexList.stream().map(p -> {
                AnnexVo annexVo = new AnnexVo();
                //赋值
                BeanUtils.copyProperties(p, annexVo);
                //上传时间转换
                annexVo.setUploadTime(DateUtils.format(p.getUploadTime(), DateUtils.DATE_TIME_PATTERN));
                //设置附件为旧附件,用以区分修改时附件状态
                annexVo.setNews(0);

                return annexVo;
            }).collect(Collectors.toList());

            vo.setAnnexVos(annexVos);
        }
        return vo;
    }

    /**
     * 删除(修改数据有效性)
     * @param id id
     * @param status 状态(1.草稿箱 2.待批箱 3.已批箱 4.完成箱 5.垃圾箱)
     */
    @Transactional(rollbackFor = Exception.class)
    public R delete(Integer id, Integer status){
        if(null == id){
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        InitStockEntity initStockReq = new InitStockEntity();
        //修改主键
        initStockReq.setId(id);
        //设置修改时间
        initStockReq.setModifyTime(new Date());
        if(OperationStatusEnum.DRAFT_BOX.getId() == status){
            //草稿箱删除：数据设为垃圾箱
            initStockReq.setStatus(OperationStatusEnum.TRASH_CAN.getId());
        }else if(OperationStatusEnum.TRASH_CAN.getId() == status){
            //垃圾箱删除：数据设为无效
            initStockReq.setValid(DataIsValidEnum.INVALID.getId());
        }
        initStockService.update(initStockReq);
        //获取明细数据
        InitStockDetailEntity detailReq = new InitStockDetailEntity();
        detailReq.setInitStockId(id);
        detailReq.setValid(DataIsValidEnum.VALID.getId());
        //获取明细
        List<InitStockDetailEntity> inventoryDetails = initStockDetailService.queryAll(detailReq);
        if(CollectionUtils.isEmpty(inventoryDetails)){
            //没有明细,只删除主表数据
            return R.build("");
        }
        for(InitStockDetailEntity detail : inventoryDetails){
            //出运明细剩余数量修改
            StockDetailEntity stockDetail = new StockDetailEntity();
            stockDetail.setId(detail.getStockDetailId());

            //明细修改
            InitStockDetailEntity planInStoreProduct = new InitStockDetailEntity();
            //设置主键
            planInStoreProduct.setId(detail.getId());
            //设置修改时间
            planInStoreProduct.setModifyTime(new Date());
            if(OperationStatusEnum.TRASH_CAN.getId() == status){
                //垃圾箱删除：数据设为无效
                //将盘点明细设为失效
                planInStoreProduct.setValid(DataIsValidEnum.INVALID.getId());
                stockDetail.setValid(DataIsValidEnum.INVALID.getId());
            }
            //修改库存明细状态
            stockDetailService.update(stockDetail);
            //修改明细状态
            initStockDetailService.update(planInStoreProduct);
        }
        return R.build("");
    }

    /**
     * 数据操作接口
     * @param req 操作类型
     * 1.提交审批 2.审批通过 3.审批退回 4.完成 5.还原
     * 箱体：1.草稿箱 2.待批箱 3.已批箱 4.完成箱 5.垃圾箱
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public R operation(OperationReq req){
        if(null == req.getId() || null == req.getOperation()){
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        InitStockEntity planInStore = new InitStockEntity();
        //设置id
        planInStore.setId(req.getId());
        if(req.getOperation() == SubmitStatusEnum.SUBMIT_APPROVE.getId()){
            //提交审批后,状态为待批箱
            //状态设为待批箱
            planInStore.setStatus(OperationStatusEnum.PENDING_BOX.getId());
        }else if(req.getOperation() == SubmitStatusEnum.APPROVE_SUCCESS.getId()){
            //审批通过,库存新增
            approved(req.getId());
            planInStore.setStatus(OperationStatusEnum.APPROVED_BOX.getId());
        }else if(req.getOperation() == SubmitStatusEnum.APPROVE_RETURN.getId()){
            //审批退回后只修改调拨状态
            //状态设为草稿箱
            planInStore.setStatus(OperationStatusEnum.DRAFT_BOX.getId());
        }else if(req.getOperation() == SubmitStatusEnum.SUCCESS.getId()){
            //将状态设为完成
            planInStore.setStatus(OperationStatusEnum.COMPLETION_BOX.getId());
        }else if(req.getOperation() == SubmitStatusEnum.REDUCTION.getId()){
            //将状态改为草稿箱
            planInStore.setStatus(OperationStatusEnum.DRAFT_BOX.getId());
        }
        //修改数据
        initStockService.update(planInStore);
        return R.build("");
    }

    /**
     * 审批
     * @param id
     */
    private void approved(Integer id){
        //获取主表信息
        InitStockEntity planInStore = initStockService.queryById(id);
        //初始化查询参数对象
        InitStockDetailEntity detailReq = new InitStockDetailEntity();
        detailReq.setInitStockId(id);
        detailReq.setValid(DataIsValidEnum.VALID.getId());
        List<InitStockDetailEntity> detailList = initStockDetailService.queryAll(detailReq);
        if(CollectionUtils.isEmpty(detailList)){
            return;
        }
        for(InitStockDetailEntity detail : detailList){
            //获取库存信息
            StockEntity stockReq = new StockEntity();
            stockReq.setLotNo(detail.getLotNo());
            stockReq.setProductCode(detail.getProductCode());
            stockReq.setSpecificationCode(detail.getSpecificationCode());
            stockReq.setWarehouseCode(detail.getWarehouseId());
            //根据库存id获取库存信息
            List<StockEntity> stockInfo = stockService.getTheSameStockInfo(stockReq);
            //数量
            BigDecimal num = detail.getProductNum();
            if(CollectionUtils.isEmpty(stockInfo)){
                //不存在同一批数据,库存直接新增
                StockEntity stock = new StockEntity();

                BeanUtils.copyProperties(detail, stock);
                stock.setParentId(detail.getId());
                //入库单号
                stock.setInStoreBillNo(planInStore.getBillNo());
                //实际数量
                stock.setRealQuantity(num);
                //实际可用数量
                stock.setRealAvailableQuantity(num);
                //可申请数量
                stock.setCanApplyQuantity(num);
                //调拨申请数量
                stock.setTransferApplyQuantity(new BigDecimal("0"));
                //出库申请数量
                stock.setOutWarehouseApply(new BigDecimal("0"));
                //入库人
                stock.setSalesman(planInStore.getInStorePerson());
                //入库人编码
                stock.setSalesmanCode(planInStore.getInStoreCode());
                //仓库编码
                stock.setWarehouseCode(detail.getWarehouseId());
                //入库日期
                stock.setInStoreDate(new Date());
                //产品类型(默认成品)
                stock.setProductType(ProductTypeEnum.END_PRODUCT.getId());
                //数据有效
                stock.setValid(DataIsValidEnum.VALID.getId());
                stockService.insert(stock);
            }else {
                //库存存在同一类型数据,则数量累加
                StockEntity stock = new StockEntity();
                //库存主键id
                stock.setId(stockInfo.get(0).getId());
                //库存实际数量
                BigDecimal oldRealQuantity = new BigDecimal("0");
                if (StringUtil.isNotEmpty((stockInfo.get(0).getRealQuantity()))) {
                    oldRealQuantity = stockInfo.get(0).getRealQuantity();
                }
                stock.setRealQuantity(num.add(oldRealQuantity));

                //库存实际可用数量
                BigDecimal oldRealAvailableQuantity = new BigDecimal("0");
                if (StringUtil.isNotEmpty((stockInfo.get(0).getRealAvailableQuantity()))) {
                    oldRealAvailableQuantity = stockInfo.get(0).getRealAvailableQuantity();
                }
                stock.setRealAvailableQuantity(num.add(oldRealAvailableQuantity));

                //库存可申请数量
                BigDecimal oldCanApplyQuantity = new BigDecimal("0");
                if (StringUtil.isNotEmpty((stockInfo.get(0).getCanApplyQuantity()))) {
                    oldCanApplyQuantity = stockInfo.get(0).getCanApplyQuantity();
                }
                stock.setCanApplyQuantity(num.add(oldCanApplyQuantity));

                //更新库存信息
                stockService.update(stock);
            }

        }
    }
    /**
     * 获取String类型不为空数据
     *
     * @param value 目标数据
     * @return 不为空数据
     */
    private String getNotNullOfStringInfo(String value) {
        if (StringUtils.isEmpty(value)) {
            return "";
        } else {
            return value;
        }
    }

    /**
     * 获取BigDecimal类型不为空的数据
     *
     * @param value 目标数据
     * @return 不为空数据
     */
    private BigDecimal getNotNullOfBigDecimalInfo(BigDecimal value) {
        if (StringUtil.isNotEmpty(value)) {
            return value;
        } else {
            return new BigDecimal("0");
        }
    }
    /**
     * 初始化统计
     *
     * @param req 查询参数
     * @return 初始化统计
     */
    public PageInfo<InitStatisticsInfoVo> getInitStatisticsByPage(InitStatisticsInfoReq req) {
        //初始化回参集合
        List<InitStatisticsInfoVo> voList = new ArrayList<>();
        //查询初始化信息
        List<InitStatisticsInfoRsp> initStatisticsInfo = initStockService.getInitStatisticsInfo(req);
        //获取分页信息
        PageInfo pageInfo = new PageInfo(initStatisticsInfo);
        if (CollectionUtils.isEmpty(initStatisticsInfo)) {
            pageInfo.setList(voList);
            return pageInfo;
        }
        for (InitStatisticsInfoRsp info : initStatisticsInfo) {
            //初始化回参实体
            InitStatisticsInfoVo vo = new InitStatisticsInfoVo();
            //赋值
            BeanUtils.copyProperties(info, vo);
            //时间处理
            vo.setCreateDate(DateUtils.format(info.getCreateDate()));

            voList.add(vo);
        }
        pageInfo.setList(voList);
        return pageInfo;
    }


    public JSONObject initStatisticsExport(InitStatisticsInfoReq req){
        //查询初始化信息
        List<InitStatisticsInfoRsp> initStatisticsInfo = initStockService.getInitStatisticsInfo(req);
        if (CollectionUtils.isEmpty(initStatisticsInfo)) {
            return null;
        }
        //初始化回参集合
        List<InitStatisticsInfoVo> voList = new ArrayList<>();
        for (InitStatisticsInfoRsp info : initStatisticsInfo) {
            //初始化回参实体
            InitStatisticsInfoVo vo = new InitStatisticsInfoVo();
            //赋值
            BeanUtils.copyProperties(info, vo);
            //时间处理
            vo.setCreateDate(DateUtils.format(info.getCreateDate()));

            voList.add(vo);
        }


        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleInitCollectionInfo();
        JSONArray data = new JSONArray();
        data.add(titleList);
        if (CollectionUtils.isEmpty(voList)) {
            obj.put("data", data);
            return obj;
        }
        excelInitCollectionInfoExport(data, voList);
        obj.put("data", data);
        return obj;
    }
    private JSONArray getTitleInitCollectionInfo() {
        JSONArray obj = new JSONArray();
        obj.add("入库单号");
        obj.add("创建时间");
        obj.add("批次号");
        obj.add("仓库名称");
        obj.add("产品编码");
        obj.add("规格编码");
        obj.add("产品数量");
        obj.add("成本单价");
        obj.add("产品中文名称");
        obj.add("产品英文名称");
        obj.add("产品中文描述");
        obj.add("产品英文描述");

        return obj;
    }
    private void excelInitCollectionInfoExport(JSONArray data, List<InitStatisticsInfoVo> list) {
        for (InitStatisticsInfoVo vo : list) {
            JSONArray infoList = new JSONArray();
            infoList.add(getNotNullOfStringInfo(vo.getBillNo()));
            infoList.add(getNotNullOfStringInfo(vo.getCreateDate()));
            infoList.add(getNotNullOfStringInfo(vo.getLotNo()));
            infoList.add(getNotNullOfStringInfo(vo.getWarehouseName()));
            infoList.add(getNotNullOfStringInfo(vo.getProductCode()));
            infoList.add(getNotNullOfStringInfo(vo.getSpecificationCode()));
            infoList.add(vo.getProductNum()==null?0:vo.getProductNum());
            infoList.add(getNotNullOfBigDecimalInfo(vo.getProductUnitPrice()));
            infoList.add(getNotNullOfStringInfo(vo.getProductCname()));
            infoList.add(getNotNullOfStringInfo(vo.getProductEname()));
            infoList.add(getNotNullOfStringInfo(vo.getProductCdesc()));
            infoList.add(getNotNullOfStringInfo(vo.getProductEdesc()));
            data.add(infoList);
        }
    }
}
